# RISC-V交叉编译工具链
CC = riscv64-unknown-elf-gcc
# -ffreestanding: 构建裸机/内核环境，不假设存在标准库
# -fno-builtin: 禁用内建函数优化，避免 printf/puts 等被折叠
CFLAGS = -mcmodel=medany -ffreestanding -fno-builtin -c
LDFLAGS = 

# 内核文件夹
KERNEL_DIR = kernel

# 查找所有.c和.S源文件
C_SOURCES = $(shell find $(KERNEL_DIR) -name "*.c")
ASM_SOURCES = $(shell find $(KERNEL_DIR) -name "*.S")

# 生成对应的.o文件列表
C_OBJECTS = $(C_SOURCES:.c=.o)
ASM_OBJECTS = $(ASM_SOURCES:.S=.o)
OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)

# 链接脚本
LINKER_SCRIPT = $(KERNEL_DIR)/kernel.ld

# 目标文件
TARGET = $(KERNEL_DIR)/kernel.elf

# 默认目标
all: $(TARGET)

# 链接生成kernel.elf
$(TARGET): $(OBJECTS) $(LINKER_SCRIPT)
	@echo "链接生成 $@"
	cd $(KERNEL_DIR) && $(CC) -T kernel.ld -o kernel.elf $(patsubst $(KERNEL_DIR)/%,%,$(OBJECTS)) -nostdlib

# 编译.c文件为.o文件
%.o: %.c
	@echo "编译 $< -> $@"
	$(CC) $(CFLAGS) $< -o $@

# 编译.S文件为.o文件  
%.o: %.S
	@echo "编译 $< -> $@"
	$(CC) $(CFLAGS) $< -o $@

# 运行QEMU
qemu: $(TARGET)
	@echo "启动QEMU虚拟机"
	qemu-system-riscv64 -machine virt -bios none -nographic -kernel kernel/kernel.elf

# 清理目标
clean:
	@echo "清理目标文件和可执行文件"
	find $(KERNEL_DIR) -name "*.o" -delete
	find $(KERNEL_DIR) -name "*.elf" -delete

# 显示帮助信息
help:
	@echo "可用目标："
	@echo "  all    - 编译并链接生成kernel.elf（默认）"
	@echo "  qemu   - 编译内核并在QEMU中运行"
	@echo "  clean  - 删除所有.o和.elf文件"
	@echo "  help   - 显示此帮助信息"

# 声明伪目标
.PHONY: all qemu clean help

# 打印调试信息（可选）
debug:
	@echo "C源文件: $(C_SOURCES)"
	@echo "汇编源文件: $(ASM_SOURCES)"
	@echo "目标文件: $(OBJECTS)"
	@echo "目标: $(TARGET)"

.PHONY: debug
